﻿#pragma once

#include <ctime>
#include <memory>
#include <string>
#include "../util/object_pool.hh"

namespace kratos {
namespace http {
class HttpBaseImpl;
}
} // namespace kratos

namespace kratos {
namespace service {

class ServiceBox;
class CommandImpl;

/**
 * 本地命令处理类.
 */
class LocalCommand {
  ServiceBox *box_{nullptr}; ///< 服务容器
    
  unique_pool_ptr<CommandImpl> stop_command_                  {nullptr}; ///< 命令, 容器关闭
  unique_pool_ptr<CommandImpl> reload_command_                {nullptr}; ///< 命令, 重载配置
  unique_pool_ptr<CommandImpl> proc_stat_command_             {nullptr}; ///< 命令, 进程信息
  unique_pool_ptr<CommandImpl> show_alloc_command_            {nullptr}; ///< 命令, 内存信息
  unique_pool_ptr<CommandImpl> show_register_service_command_ {nullptr}; ///< 命令, 获取本容器已经注册的服务
  unique_pool_ptr<CommandImpl> show_remote_service_command_   {nullptr}; ///< 命令, 获取容器相关联的服务
  unique_pool_ptr<CommandImpl> show_config_command_           {nullptr}; ///< 命令，显示配置的命令
  unique_pool_ptr<CommandImpl> show_sys_alloc_command_        {nullptr}; ///< 命令，显示容器分配器信息
  unique_pool_ptr<CommandImpl> force_gc_command_              {nullptr}; ///< 命令，强制释放所有池内内存
  unique_pool_ptr<CommandImpl> change_argument_setting_       {nullptr}; ///< 命令，改变命令行设置
  // TODO show_argument

  constexpr static std::time_t DEFAULT_TIMEOUT = 5000;     ///< 默认超时时间，毫秒
  constexpr static const char* DEFAULT_HOST = "127.0.0.1"; ///< 默认的连接地址
  constexpr static int         DEFAULT_PORT = 6889;        ///< 默认的连接端口

public:
  /**
   * 构造.
   *
   * \param box 服务容器
   */
  LocalCommand(ServiceBox *box);
  /**
   * 析构.
   *
   */
  ~LocalCommand();
  /**
   * 启动.
   *
   * \return true或者false
   */
  auto start() -> bool;
  /**
   * 停止.
   *
   * \return
   */
  auto stop() -> void;
  /**
   * 执行命令.
   *
   * \param command 命令
   * \return
   */
  auto do_command(const std::string &command) -> void;

private:
  /**
   * 发送命令到本地服务容器
   *
   * \param command 命令
   * \param host 本地地址
   * \param port 本地端口
   * \return
   */
  auto send_command(const std::string &command, const std::string &host,
    int port) -> void;
  /**
   * 注册本地命令.
   *
   * \return
   */
  auto register_all_command() -> void;
  /**
   * 向日志写入配置.
   *
   * \return
   */
  auto get_config() -> std::string;
  /**
   * 打印分配信息.
   * 
   * \return 
   */
  auto print_json(const char* str, std::size_t count) -> void;
};

} // namespace service
} // namespace kratos
